<!--new-->

<template>
    <div class="admin-page">
        <div class="page-header">
            <div class="table-header">
                <div class="table-actions">
                    <el-button type="primary" @click="handleAddAdmin" size="small" icon="el-icon-plus">添加产品
                    </el-button>
                </div>

            </div>
            <div style="display: flex;justify-content: space-between">
                <div style="display: flex; flex-wrap: wrap; align-items: center; gap: 15px; margin-bottom: 15px;">
                    <div style="display: flex;text-align: center;line-height: 36px;" class="grid-content bg-purple">
                        产品名称:
                        <el-input v-model="form.search" size="small"
                                  style="width: 70%;margin-left: 10px;"></el-input>
                    </div>
                    <div style="display: flex;text-align: center;line-height: 36px;" class="grid-content bg-purple">
                        banner位置：
                        <el-select v-model="form.type" size="small" style="width: 110px;" placeholder="全部" clearable>
                            <el-option
                                v-for="(item, index) in typeList"
                                :key="index"
                                :label="item.type_name"
                                :value="String(item.type_id)"
                            ></el-option>
                        </el-select>
                    </div>
                </div>
                <div style="display: flex; align-items: center; gap: 15px; margin-bottom: 15px;">
                    <el-button type="primary" size="small" @click="toSearch">搜索</el-button>
                    <el-button type="success" size="small" @click="reset">重置</el-button>
                </div>
            </div>
            <el-table  height="560" :data="adminList" border style="width: 100%;overflow-y: auto"
                      :header-cell-style="{background:'#FAFAFA',color:'#666', fontSize:'13px'}" size="small">
                <el-table-column prop="id" label="ID" align="center" width="80"/>
                <el-table-column prop="name" label="产品名"/>
                <el-table-column prop="thumb" label="产品封面" width="80px">
                    <template slot-scope="scope">
                        <img style="width: 50px;height: 50px" :src="$appConfig.imgPath + scope.row.thumb"/>
                    </template>
                </el-table-column>
                <el-table-column prop="type" label="banner位置" width="100px">
                    <template slot-scope="scope">
                        <span>{{ getTypeName(scope.row.type) }}</span>
                    </template>
                </el-table-column>
                <el-table-column prop="url" label="banner跳转位置"/>
                <el-table-column prop="sort" label="排序"/>
                <el-table-column label="操作" width="300" align="center">
                    <template slot-scope="scope">
                        <el-button type="text" size="small" @click="handleEdit(scope.row)" icon="el-icon-edit">编辑
                        </el-button>
                        <el-button type="text" size="small" @click="handleDelete(scope.row)" icon="el-icon-delete"
                                   class="delete-btn">删除
                        </el-button>
                        <el-button type="success" size="small" @click="handleStateChange(scope.row)"
                                   :style="{ backgroundColor: scope.row.state === 0? 'red' : '#67c23a' }">
                            {{ scope.row.state === 0 ? '隐藏' : '显示' }}
                        </el-button>
                    </template>
                </el-table-column>
            </el-table>
            <el-pagination @size-change="handleSizeChange" @current-change="handleCurrentChange"
                           :current-page="currentPage" :page-sizes="[10, 20, 30, 40]" :page-size="pageSize"
                           layout="total,  pager, next, jumper" :total="total"/>
            <!-- 添加商品对话框 -->
            <el-dialog title="添加产品" :visible.sync="addDialogVisible" width="700px" :close-on-click-modal="false">
                <el-form :model="adminForm" :rules="adminRules" ref="adminForm" label-width="100px" size="small">
                    <el-form-item label="产品名" prop="name">
                        <el-input style="width: 90%;" v-model="adminForm.name"/>
                    </el-form-item>
                    <el-form-item label="banner位置" prop="name">
                        <el-select v-model="adminForm.type" size="small" style="width: 110px;" placeholder="全部" clearable>
                            <el-option
                                v-for="(item, index) in typeList"
                                :key="index"
                                :label="item.type_name"
                                :value="String(item.type_id)"
                            ></el-option>
                        </el-select>
                    </el-form-item>
                    <el-form-item label="商品分类" prop="clas_id">
                        <el-cascader
                            v-model="adminForm.clas_id"
                            :options="categoryList"
                            :props="{ value: 'id', label: 'name', children: 'children', emitPath: false, checkStrictly: true }"
                            clearable
                            placeholder="请选择"
                            size="small"
                            style="width: 90%;"
                        />
                    </el-form-item>
                    <el-form-item label="跳转地址" prop="name">
                        <el-input style="width: 90%;" v-model="adminForm.url"/>
                    </el-form-item>
                    <el-form-item label="排序" prop="name">
                        <el-input style="width: 90%;" v-model="adminForm.sort"/>
                    </el-form-item>
                    <el-form-item label="封面图" prop="thumb">
                        <el-upload
                            class="avatar-uploader"
                            action="/admin/shop/imgUpload"
                            :headers="{ token: userInfo.token }"
                            :show-file-list="false"
                            :on-success="handleCoverSuccess"
                            :before-upload="beforeCoverUpload">
                            <img v-if="adminForm.thumb" :src="$appConfig.imgPath + adminForm.thumb"
                                 class="avatar">
                            <i v-else class="el-icon-plus avatar-uploader-icon"></i>
                        </el-upload>
                    </el-form-item>
                    <el-form-item label="是否显示">
                        <el-radio-group v-model="adminForm.state">
                            <el-radio :label="1">显示</el-radio>
                            <el-radio :label="0">隐藏</el-radio>
                        </el-radio-group>
                    </el-form-item>
                </el-form>
                <div slot="footer" class="dialog-footer">
                    <el-button @click="addDialogVisible = false" size="small">取消</el-button>
                    <el-button type="primary" @click="submitForm" size="small">确定</el-button>
                </div>
            </el-dialog>
            <!-- 编辑商品对话框 -->
            <el-dialog title="编辑商品" :visible.sync="editDialogVisible" width="700px" :close-on-click-modal="false">
                <el-form :model="adminForm" :rules="adminRules" ref="adminForm" label-width="100px" size="small">
                    <el-form-item label="产品名" prop="name">
                        <el-input style="width: 90%;" v-model="adminForm.name"/>
                    </el-form-item>
                    <el-form-item label="banner位置" prop="name">
                        <el-select v-model="adminForm.type" size="small" style="width: 110px;" placeholder="全部" clearable>
                            <el-option
                                v-for="(item, index) in typeList"
                                :key="index"
                                :label="item.type_name"
                                :value="String(item.type_id)"
                            ></el-option>
                        </el-select>
                    </el-form-item>
                    <el-form-item label="商品分类" prop="clas_id">
                        <el-cascader
                            v-model="adminForm.clas_id"
                            :options="categoryList"
                            :props="{ value: 'id', label: 'name', children: 'children', emitPath: false, checkStrictly: true }"
                            clearable
                            placeholder="请选择"
                            size="small"
                            style="width: 90%;"
                        />
                    </el-form-item>
                    <el-form-item label="跳转地址" prop="name">
                        <el-input style="width: 90%;" v-model="adminForm.url"/>
                    </el-form-item>
                    <el-form-item label="排序" prop="name">
                        <el-input style="width: 90%;" v-model="adminForm.sort"/>
                    </el-form-item>
                    <el-form-item label="封面图" prop="thumb">
                        <el-upload
                            class="avatar-uploader"
                            action="/admin/shop/imgUpload"
                            :headers="{ token: userInfo.token }"
                            :show-file-list="false"
                            :on-success="handleCoverSuccess"
                            :before-upload="beforeCoverUpload">
                            <img v-if="adminForm.thumb" :src="$appConfig.imgPath + adminForm.thumb"
                                 class="avatar">

<!--                            <img v-if="adminForm.thumb" :src="`http://www.ts.com/${adminForm.thumb}`"-->
<!--                                 class="avatar">-->
                            <i v-else class="el-icon-plus avatar-uploader-icon"></i>
                        </el-upload>
                    </el-form-item>
<!--                                        <el-form-item label="商品详情图" prop="thumb">-->
<!--                                            <el-upload-->
<!--                                                class="detail-uploader"-->
<!--                                                action="/admin/shop/imgUpload"-->
<!--                                                :headers="{ Authorization: 'Bearer ' + userInfo.token }"-->
<!--                                                list-type="picture-card"-->
<!--                                                :file-list="detailImages"-->
<!--                                                :on-success="handleDetailSuccess"-->
<!--                                                :before-upload="beforeDetailUpload"-->
<!--                                                :on-remove="handleRemove"-->
<!--                                                :on-preview="handlePreview"-->
<!--                                                multiple>-->
<!--                                                <i class="el-icon-plus"></i>-->
<!--                                            </el-upload>-->
<!--                                        </el-form-item>-->

                    <el-form-item label="是否显示">
                        <el-radio-group v-model="adminForm.state">
                            <el-radio :label="1">显示</el-radio>
                            <el-radio :label="0">隐藏</el-radio>
                        </el-radio-group>
                    </el-form-item>

                </el-form>
                <div slot="footer" class="dialog-footer">
                    <el-button @click="editDialogVisible = false" size="small">取消</el-button>
                    <el-button type="primary" @click="submitForm" size="small">确定</el-button>
                </div>
            </el-dialog>
            <!-- 二维码放大弹窗 -->
            <el-dialog title="二维码" :visible.sync="qrCodeDialogVisible" width="300px" :close-on-click-modal="true">
                <div style="text-align: center;">
                    <qrcode-vue :value="currentQRCode" :size="200" level="H"/>
                </div>
            </el-dialog>
        </div>
    </div>
</template>

<script>
import {mapState} from "vuex";
import QrcodeVue from 'qrcode.vue';

export default {
    data() {
        return {
            adminList: [],
            currentPage: 1,
            pageSize: 25,
            total: 0,
            form: {
                search: "",
                clas_id: "",
                state: "",
                type:''
            },
            typeList:[

            ],
            categoryList:[

            ],
            addDialogVisible: false,
            editDialogVisible: false,
            adminForm: {
                name: '',
                thumb: '',
                type: "",
                state: 1,
                sort: '1',
                url:"",
                clas_id: null,
            },
            detailImages: [],
            previewVisible: false,
            previewImage: '',
            adminRules: {
                name: [{required: true, message: '请输入产品名称', trigger: 'blur'}],
            }
            ,

            statusList:
                [
                    {
                        id: 1,
                        name: "显示"
                    }, {
                    id: 0, name: '隐藏'
                }

                ],
            imageUrl:
                '',
            imageUrl1:
                '',
            qrCodeDialogVisible: false,
            currentQRCode: ''
        };
    },
    mounted() {
        this.fetchAdminList();
        this.typeLists();
        this.categoryLists();
    },
    computed: {
        ...mapState(["userInfo"]),
    },
    components: {
        QrcodeVue
    },
    methods: {
        getTypeName(typeId) {
            const typeItem = this.typeList.find(item => item.type_id == typeId);
            return typeItem ? typeItem.type_name : '未知类型';
        },
        categoryLists() {
            this.$http.get('/admin/clas/getCateList').then(result => {
                if (result.code === 200) {
                    this.categoryList = result.data;
                }
            });
        },
        getCategoryName(id, list = this.categoryList) {
            for (let item of list) {
                if (item.id == id) return item.name;
                if (item.children) {
                    const found = this.getCategoryName(id, item.children);
                    if (found) return found;
                }
            }
            return '未知分类';
        },
        fetchAdminList() {
            const params = {
                page: this.currentPage,
                limit: this.pageSize
            };
            this.$http.get('/admin/slide/lists', {params}).then(result => {
                if (result.code === 200) {
                    const dataObj = result.data.data;
                    const newListData = [];
                    for (const key in dataObj) {
                        if (dataObj.hasOwnProperty(key)) {
                            newListData.push(dataObj[key]);
                        }
                    }
                    this.adminList = newListData;
                    this.total = result.data.total || newListData.length;
                } else {
                    this.$message.error(result.msg);
                }
            });
        },
        typeLists() {
            const params = {
                page: this.currentPage,
                limit: this.pageSize
            };
            this.$http.get('/admin/slide/getType', {params}).then(result => {
                if (result.code === 200) {
                  this.typeList = result.data
                }
            });
        },
        handleSizeChange(val) {
            this.pageSize = val;
            this.fetchAdminList();
        },
        handleCurrentChange(val) {
            this.currentPage = val;
            this.fetchAdminList();
        },
        handleAddAdmin() {
            this.adminForm = {
                name: '',
                thumb: '',
                type: "",
                sort: '1',
                state: 1,
                url:"",
                clas_id: null,
            };
            this.$refs.adminForm && this.$refs.adminForm.clearValidate();
            this.addDialogVisible = true;
        },
        handleEdit(row) {
            this.$http.get(`/admin/slide/edit`, {params: {id: row.id}}).then(result => {
                if (result.code == 200) {
                    this.adminForm.name = row.name;
                    this.adminForm.thumb = row.thumb;
                    this.adminForm.type = String(row.type);
                    this.adminForm.state = row.state;
                    this.adminForm.sort = row.sort;
                    this.adminForm.id = row.id;
                    this.adminForm.url = row.url;
                    // 对于 el-cascader，如果 emitPath: false，直接使用 clas_id
                    this.adminForm.clas_id = row.clas_id ? Number(row.clas_id) : null;
                    this.editDialogVisible = true;
                    this.$nextTick(() => {
                        this.$refs.adminForm && this.$refs.adminForm.clearValidate();
                    });
                } else {
                    this.$message.error(result.msg || '获取详情失败');
                }
            }).catch(error => {
                console.error('获取详情失败:', error);
                this.$message.error('获取详情失败');
            });
        },

        // 封面图上传相关方法
        handleCoverSuccess(res, file) {
            if (res.code === 200 && res.data) {
                try {
                    const imgPath = res.data;
                    this.adminForm.thumb = Array.isArray(imgPath) ? imgPath.join('') : imgPath;
                    this.$nextTick(() => {
                        this.$forceUpdate();
                    });
                    this.$message.success('封面图上传成功');
                } catch (error) {
                    console.error('处理封面图上传响应失败:', error);
                    this.$message.error('处理封面图数据失败');
                }
            } else {
                this.$message.error(res.msg || '封面图上传失败');
            }
        },
        beforeCoverUpload(file) {
            const isValidFormat = ['image/jpeg', 'image/png'].includes(file.type);
            const isLt20M = file.size / 1024 / 1024 < 20;

            if (!isValidFormat) {
                this.$message.error('封面图只能是 JPG/PNG 格式!');
                return false;
            }
            if (!isLt20M) {
                this.$message.error('封面图大小不能超过 20MB!');
                return false;
            }
            return true;
        },
        // 详情图上传相关方法
        handleDetailSuccess(res, file) {
            if (res.code === 200 && res.data) {
                try {
                    const imgPath = Array.isArray(res.data) ? res.data.join('') : res.data;
                    const newImages = this.adminForm.thumb ? this.adminForm.thumb.split(',') : [];
                    newImages.push(imgPath);
                    this.adminForm.thumb = newImages.join(',');
                    this.detailImages.push({
                        url: imgPath,
                        name: file.name
                    });
                    this.$nextTick(() => {
                        this.$forceUpdate();
                    });
                    this.$message.success('详情图上传成功');
                } catch (error) {
                    console.error('处理详情图上传响应失败:', error);
                    this.$message.error('处理详情图数据失败');
                }
            } else {
                this.$message.error(res.msg || '详情图上传失败');
            }
        },
        beforeDetailUpload(file) {
            const isValidFormat = ['image/jpeg', 'image/png'].includes(file.type);
            const isLt20M = file.size / 1024 / 1024 < 20;

            if (!isValidFormat) {
                this.$message.error('详情图只能是 JPG/PNG 格式!');
                return false;
            }
            if (!isLt20M) {
                this.$message.error('详情图大小不能超过 20MB!');
                return false;
            }
            return true;
        },
        handleRemove(file) {
            const index = this.detailImages.findIndex(item => item.url === file.url);
            if (index > -1) {
                this.detailImages.splice(index, 1);
                const images = this.adminForm.thumb.split(',');
                images.splice(index, 1);
                this.adminForm.thumb = images.join(',');
            }
        },
        handlePreview(file) {
            this.previewImage = file.url;
            this.previewVisible = true;
        },
        toSearch() {
            // 合并搜索表单数据和 type 参数
            const params = {
                ...this.form,
                limit: 1
            };
            this.$http.get('/admin/slide/lists', { params }).then(result => {
                if (result.code === 200) {
                    const dataObj = result.data.data;
                    const newListData = [];
                    for (const key in dataObj) {
                        if (dataObj.hasOwnProperty(key)) {
                            newListData.push(dataObj[key]);
                        }
                    }
                    this.adminList = newListData;
                    this.total = result.data.total || newListData.length;
                } else {
                    this.$message.error(result.msg);
                }
            });
        },
        reset() {
            this.form = {
                search: "",
                clas_id: "",
                state: "",
                type: ""
            }
            this.fetchAdminList()
        },
        handleStateChange(row) {
            const newState = row.state === 1 ? 0 : 1;
            this.$http.post('/admin/slide/del', {
                name: row.name,
                type: row.type,
                thumb: row.thumb,
                clas_id: row.clas_id,
                id: row.id,
                state: newState
            }).then(result => {
                if (result.code === 200) {
                    this.$message.success('状态更新成功');
                    this.fetchAdminList();
                } else {
                    this.$message.error(result.msg || '状态更新失败');
                }
            });
        },
        handleDelete(data) {
            this.$confirm('此操作将永久删除该文件, 是否继续?', '提示', {
                confirmButtonText: '确定',
                cancelButtonText: '取消',
                type: 'warning'
            }).then(() => {
                // 用户点击了确定按钮
                this.$http.post('/admin/slide/del', {
                    id: data.id,
                    state: "-1"
                }).then(result => {
                    if (result.code === 200) {
                        this.$message.success(result.msg);
                        this.fetchAdminList();
                    } else {
                        this.$message.error(result.msg);
                    }
                });
            }).catch(() => {
                // 用户点击了取消按钮
                this.$message({
                    type: 'info',
                    message: '已取消删除'
                });
            });
        },
        submitForm() {
            if (!this.adminForm.thumb || !this.adminForm.thumb) {
                this.$message.error('请确保已上传封面图和详情图');
                return;
            }
            this.$refs.adminForm.validate(valid => {
                if (valid) {
                    // 假设后端接口需要 id 来确定要编辑的记录，这里将 adminForm 中的 id 一起传递
                    let postData = {
                        ...this.adminForm,
                        type: Number(this.adminForm.type)
                    }
                    this.$http.post('/admin/slide/edit', postData).then(result => {
                        if (result.code === 200) {
                            this.$message.success(result.msg);
                            this.addDialogVisible = false;
                            this.editDialogVisible = false;
                            this.fetchAdminList();
                        } else {
                            this.$message.error(result.msg);
                        }
                    });
                }
            });
        }
    }
};
</script>
<style lang="less" scoped>
.avatar-uploader .el-upload {
    border: 1px dashed #d9d9d9;
    border-radius: 6px;
    cursor: pointer;
    position: relative;
    overflow: hidden;
}

.avatar-uploader .el-upload:hover {
    border-color: #409EFF;
}

.avatar-uploader-icon {
    font-size: 28px;
    color: #8c939d;
    width: 178px;
    height: 178px;
    line-height: 178px;
    text-align: center;
}

.avatar {
    width: 178px;
    height: 178px;
    display: block;
}

/deep/ .el-dialog__header {
    padding: 10px !important;
    text-align: center;
}

.admin-page {
    padding: 24px;
    background: #fff;
    border-radius: 8px;
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.06);

    .page-header {
        margin-bottom: 24px;
        padding-bottom: 16px;
        border-bottom: 1px solid #f0f2f5;

        .header-title {
            font-size: 20px;
            font-weight: 600;
            color: #1f2937;
            line-height: 1.4;
        }
    }

    .table-header {
        margin-bottom: 24px;
        display: flex;
        justify-content: space-between;
        align-items: center;

        .table-title {
            font-size: 16px;
            font-weight: 500;
            color: #374151;
        }

        .table-actions {
            .el-button {
                margin-left: 12px;
                transition: all 0.3s;

                &:hover {
                    transform: translateY(-1px);
                }
            }
        }
    }

    .el-tabs {
        margin-top: 16px;

        :deep(.el-tabs__header) {
            margin-bottom: 28px;
            border-bottom: 2px solid #f0f2f5;
        }

        :deep(.el-tabs__item) {
            font-size: 15px;
            padding: 0 28px;
            height: 44px;
            line-height: 44px;
            transition: all 0.3s;

            &.is-active {
                color: #2563eb;
                font-weight: 500;
            }

            &:hover {
                color: #2563eb;
            }
        }

        :deep(.el-tabs__active-bar) {
            height: 2px;
            background-color: #2563eb;
            transition: all 0.3s cubic-bezier(0.645, 0.045, 0.355, 1);
        }
    }

    .el-table {
        margin-top: 12px;
        border-radius: 8px;
        overflow: hidden;

        :deep(th) {
            background-color: #f9fafb !important;
            font-weight: 500;
            color: #4b5563;
        }

        :deep(td) {
            padding: 12px 0;
        }

        .delete-btn {
            color: #dc2626;
            transition: all 0.3s;

            &:hover {
                color: #ef4444;
            }
        }
    }

    .el-pagination {
        margin-top: 24px;
        padding: 12px 0;
        text-align: right;

        :deep(.el-pagination__total) {
            margin-right: 12px;
        }

        :deep(.btn-prev),
        :deep(.btn-next) {
            border-radius: 4px;
            background-color: #fff;
        }

        :deep(.el-pager li) {
            border-radius: 4px;
            background-color: #fff;

            &.active {
                background-color: #2563eb;
            }
        }
    }

    .el-dialog {
        border-radius: 12px;
        overflow: hidden;
        max-height: 90vh;
        display: flex;
        flex-direction: column;

        :deep(.el-dialog__header) {
            padding: 20px 24px !important;
            border-bottom: 1px solid #f0f2f5;
            margin: 0;

            .el-dialog__title {
                font-size: 18px;
                font-weight: 600;
                color: #1f2937;
            }
        }

        :deep(.el-dialog__body) {
            padding: 32px 24px;
            flex: 1;
            overflow-y: auto;

            .el-form-item {
                .el-input,
                .el-select {
                    width: 320px;
                }
            }
        }

        :deep(.el-tree) {
            max-height: 300px;
            overflow-y: auto;
            border: 1px solid #DCDFE6;
            border-radius: 4px;
            padding: 10px;
        }

        :deep(.el-dialog__footer) {
            padding: 16px 24px;
            border-top: 1px solid #f0f2f5;
        }

        :deep(.el-form-item__label) {
            font-weight: 500;
            color: #374151;
        }

        :deep(.el-button) {
            padding: 8px 20px;
            transition: all 0.3s;

            &:hover {
                transform: translateY(-1px);
            }
        }
    }
}

.tip-text {
    font-size: 12px;
    color: #999;
    margin-top: 5px;
    display: block;
}

/deep/ .el-tab-pane {
    height: 650px;
    overflow-y: auto;
}

</style>


<el-dialog title="二维码" :visible.sync="qrCodeDialogVisible" width="300px" :close-on-click-modal="false">
<div style="text-align: center;">
    <qrcode-vue :value="currentQRCode" :size="200" level="H"/>
</div>
</el-dialog>
}




<!--old-->
<!--

<template>
    <div class="admin-page">
        <div class="page-header">
            <div class="table-header">
                <div class="table-actions">
                    <el-button type="primary" @click="handleAddAdmin" size="small" icon="el-icon-plus">添加产品
                    </el-button>
                </div>

            </div>
            <div style="display: flex;justify-content: space-between">
                <div style="display: flex; flex-wrap: wrap; align-items: center; gap: 15px; margin-bottom: 15px;">
                    <div style="display: flex;text-align: center;line-height: 36px;" class="grid-content bg-purple">
                        产品名称:
                        <el-input v-model="form.search" size="small"
                                  style="width: 70%;margin-left: 10px;"></el-input>
                    </div>
                </div>
                <div style="display: flex; align-items: center; gap: 15px; margin-bottom: 15px;">
                    <el-button type="primary" size="small" @click="toSearch">搜索</el-button>
                    <el-button type="success" size="small" @click="reset">重置</el-button>
                </div>
            </div>
            <el-table  height="560" :data="adminList" border style="width: 100%;overflow-y: auto"
                       :header-cell-style="{background:'#FAFAFA',color:'#666', fontSize:'13px'}" size="small">
                <el-table-column prop="id" label="ID" align="center" width="80"/>
                <el-table-column prop="name" label="产品名"/>
                <el-table-column prop="thumb" label="产品封面" width="80px">
                    <template slot-scope="scope">
                        <img style="width: 50px;height: 50px"  :src="$appConfig.imgPath + scope.row.thumb"/>
                    </template>
                </el-table-column>
                <el-table-column label="操作" width="300" align="center">
                    <template slot-scope="scope">
                        <el-button type="text" size="small" @click="handleEdit(scope.row)" icon="el-icon-edit">编辑
                        </el-button>
                        <el-button type="text" size="small" @click="handleDelete(scope.row)" icon="el-icon-delete"
                                   class="delete-btn">删除
                        </el-button>
                        <el-button type="success" size="small" @click="handleStateChange(scope.row)"
                                   :style="{ backgroundColor: scope.row.state === 0? 'red' : '#67c23a' }">
                            {{ scope.row.state === 0 ? '隐藏' : '显示' }}
                        </el-button>
                    </template>
                </el-table-column>
            </el-table>
            <el-pagination @size-change="handleSizeChange" @current-change="handleCurrentChange"
                           :current-page="currentPage" :page-sizes="[10, 20, 30, 40]" :page-size="pageSize"
                           layout="total,  pager, next, jumper" :total="total"/>
            &lt;!&ndash; 添加商品对话框 &ndash;&gt;
            <el-dialog title="添加产品" :visible.sync="addDialogVisible" width="700px" :close-on-click-modal="false">
                <el-form :model="adminForm" :rules="adminRules" ref="adminForm" label-width="100px" size="small">
                    <el-form-item label="产品名" prop="name">
                        <el-input style="width: 90%;" v-model="adminForm.name"/>
                    </el-form-item>
                    <el-form-item label="封面图" prop="thumb">
                        <el-upload
                            class="avatar-uploader"
                            action="/admin/shop/imgUpload"
                            :headers="{ token: userInfo.token }"
                            :show-file-list="false"
                            :on-success="handleCoverSuccess"
                            :before-upload="beforeCoverUpload">
                            <img v-if="adminForm.thumb" :src="$appConfig.imgPath + adminForm.thumb"
                                 class="avatar">
                            <i v-else class="el-icon-plus avatar-uploader-icon"></i>
                        </el-upload>
                    </el-form-item>
                    <el-form-item label="是否显示">
                        <el-radio-group v-model="adminForm.state">
                            <el-radio :label="1">显示</el-radio>
                            <el-radio :label="0">隐藏</el-radio>
                        </el-radio-group>
                    </el-form-item>
                </el-form>
                <div slot="footer" class="dialog-footer">
                    <el-button @click="addDialogVisible = false">取消</el-button>
                    <el-button type="primary" @click="submitForm">确定</el-button>
                </div>
            </el-dialog>
            &lt;!&ndash; 编辑商品对话框 &ndash;&gt;
            <el-dialog title="编辑商品" :visible.sync="editDialogVisible" width="700px" :close-on-click-modal="false">
                <el-form :model="adminForm" :rules="adminRules" ref="adminForm" label-width="100px" size="small">
                    <el-form-item label="产品名" prop="name">
                        <el-input style="width: 90%;" v-model="adminForm.name"/>
                    </el-form-item>
                    <el-form-item label="封面图" prop="thumb">
                        <el-upload
                            class="avatar-uploader"
                            action="/admin/shop/imgUpload"
                            :headers="{ token: userInfo.token }"
                            :show-file-list="false"
                            :on-success="handleCoverSuccess"
                            :before-upload="beforeCoverUpload">
                            <img v-if="adminForm.thumb" :src="$appConfig.imgPath + adminForm.thumb" class="avatar">
                            <i v-else class="el-icon-plus avatar-uploader-icon"></i>
                        </el-upload>
                    </el-form-item>

                    <el-form-item label="是否显示">
                        <el-radio-group v-model="adminForm.state">
                            <el-radio :label="1">显示</el-radio>
                            <el-radio :label="0">隐藏</el-radio>
                        </el-radio-group>
                    </el-form-item>

                </el-form>
                <div slot="footer" class="dialog-footer">
                    <el-button @click="editDialogVisible = false">取消</el-button>
                    <el-button type="primary" @click="submitForm">确定</el-button>
                </div>
            </el-dialog>
            &lt;!&ndash; 二维码放大弹窗 &ndash;&gt;
            <el-dialog title="二维码" :visible.sync="qrCodeDialogVisible" width="300px" :close-on-click-modal="true">
                <div style="text-align: center;">
                    <qrcode-vue :value="currentQRCode" :size="200" level="H"/>
                </div>
            </el-dialog>
        </div>
    </div>
</template>

<script>
import {mapState} from "vuex";
import QrcodeVue from 'qrcode.vue';

export default {
    data() {
        return {
            adminList: [],
            currentPage: 1,
            pageSize: 25,
            total: 0,
            form: {
                search: "",
                clas_id: "",
                state: "",
            },
            addDialogVisible: false,
            editDialogVisible: false,
            adminForm: {
                name: '',
                thumb: '',
                content: '',
                type: 1,
                is_divide: 2,
                sort: '',
                state: 1
            },
            detailImages: [],
            previewVisible: false,
            previewImage: '',
            adminRules: {
                name: [{required: true, message: '请输入产品名称', trigger: 'blur'}],
            }
            ,

            statusList:
                [
                    {
                        id: 1,
                        name: "显示"
                    }, {
                    id: 0, name: '隐藏'
                }

                ],
            imageUrl:
                '',
            imageUrl1:
                '',
            qrCodeDialogVisible: false,
            currentQRCode: ''
        };
    },
    mounted() {
        this.fetchAdminList();
    },
    computed: {
        ...mapState(["userInfo"]),
    },
    components: {
        QrcodeVue
    },
    methods: {

        fetchAdminList() {
            const params = {
                type: 1,
                page: this.currentPage,
                limit: this.pageSize
            };
            this.$http.get('/admin/single/lists', {params}).then(result => {
                if (result.code === 200) {
                    const dataObj = result.data.data;
                    const newListData = [];
                    for (const key in dataObj) {
                        if (dataObj.hasOwnProperty(key)) {
                            newListData.push(dataObj[key]);
                        }
                    }
                    this.adminList = newListData;
                    this.total = result.data.total || newListData.length;
                } else {
                    this.$message.error(result.msg);
                }
            });
        },
        handleSizeChange(val) {
            this.pageSize = val;
            this.fetchAdminList();
        },
        handleCurrentChange(val) {
            this.currentPage = val;
            this.fetchAdminList();
        },
        handleAddAdmin() {
            this.adminForm = {
                name: '',
                thumb: '',
                content: '',
                type: 1,
                is_divide: 2,
                sort: '',
                state: 1
            };
            this.$refs.adminForm && this.$refs.adminForm.clearValidate();
            this.addDialogVisible = true;
        },
        handleEdit(row) {
            // 调用接口获取详细数据
            this.$http.get(`/admin/single/edit`, {params: {id: row.id}}).then(result => {
                if (result.code == 200) {
                    this.adminForm.name = row.name;
                    this.adminForm.thumb = row.thumb;
                    this.adminForm.thumb = row.thumb;
                    this.adminForm.content = row.content;
                    this.adminForm.type = row.type;
                    this.adminForm.is_divide = row.is_divide;
                    this.adminForm.state = row.state;
                    this.adminForm.sort = row.sort;
                    this.adminForm.id = row.id;
                    this.editDialogVisible = true;

                    // 等待 DOM 更新后设置表单验证状态
                    this.$nextTick(() => {
                        this.$refs.adminForm && this.$refs.adminForm.clearValidate();
                    });
                } else {
                    this.$message.error(result.msg || '获取详情失败');
                }
            }).catch(error => {
                console.error('获取详情失败:', error);
                this.$message.error('获取详情失败');
            });
        },

        // 封面图上传相关方法
        handleCoverSuccess(res, file) {
            if (res.code === 200 && res.data) {
                try {
                    const imgPath = res.data;
                    this.adminForm.thumb = Array.isArray(imgPath) ? imgPath.join('') : imgPath;
                    this.$nextTick(() => {
                        this.$forceUpdate();
                    });
                    this.$message.success('封面图上传成功');
                } catch (error) {
                    console.error('处理封面图上传响应失败:', error);
                    this.$message.error('处理封面图数据失败');
                }
            } else {
                this.$message.error(res.msg || '封面图上传失败');
            }
        },
        beforeCoverUpload(file) {
            const isValidFormat = ['image/jpeg', 'image/png'].includes(file.type);
            const isLt20M = file.size / 1024 / 1024 < 20;

            if (!isValidFormat) {
                this.$message.error('封面图只能是 JPG/PNG 格式!');
                return false;
            }
            if (!isLt20M) {
                this.$message.error('封面图大小不能超过 20MB!');
                return false;
            }
            return true;
        },
        // 详情图上传相关方法
        handleDetailSuccess(res, file) {
            if (res.code === 200 && res.data) {
                try {
                    const imgPath = Array.isArray(res.data) ? res.data.join('') : res.data;
                    const newImages = this.adminForm.thumb ? this.adminForm.thumb.split(',') : [];
                    newImages.push(imgPath);
                    this.adminForm.thumb = newImages.join(',');
                    this.detailImages.push({
                        url: imgPath,
                        name: file.name
                    });
                    this.$nextTick(() => {
                        this.$forceUpdate();
                    });
                    this.$message.success('详情图上传成功');
                } catch (error) {
                    console.error('处理详情图上传响应失败:', error);
                    this.$message.error('处理详情图数据失败');
                }
            } else {
                this.$message.error(res.msg || '详情图上传失败');
            }
        },
        beforeDetailUpload(file) {
            const isValidFormat = ['image/jpeg', 'image/png'].includes(file.type);
            const isLt20M = file.size / 1024 / 1024 < 20;

            if (!isValidFormat) {
                this.$message.error('详情图只能是 JPG/PNG 格式!');
                return false;
            }
            if (!isLt20M) {
                this.$message.error('详情图大小不能超过 20MB!');
                return false;
            }
            return true;
        },
        handleRemove(file) {
            const index = this.detailImages.findIndex(item => item.url === file.url);
            if (index > -1) {
                this.detailImages.splice(index, 1);
                const images = this.adminForm.thumb.split(',');
                images.splice(index, 1);
                this.adminForm.thumb = images.join(',');
            }
        },
        handlePreview(file) {
            this.previewImage = file.url;
            this.previewVisible = true;
        },
        toSearch() {
            // 合并搜索表单数据和 type 参数
            const params = {
                ...this.form,
                type: 1,
                limit: 1
            };
            this.$http.get('/admin/single/lists', { params }).then(result => {
                if (result.code === 200) {
                    const dataObj = result.data.data;
                    const newListData = [];
                    for (const key in dataObj) {
                        if (dataObj.hasOwnProperty(key)) {
                            newListData.push(dataObj[key]);
                        }
                    }
                    this.adminList = newListData;
                    this.total = result.data.total || newListData.length;
                } else {
                    this.$message.error(result.msg);
                }
            });
        },
        reset() {
            this.form = {
                search: "",
                clas_id: "",
                state: "",
                type: ""
            }
            this.fetchAdminList()
        },
        handleStateChange(row) {
            const newState = row.state === 1 ? 0 : 1;
            this.$http.post('/admin/single/del', {
                name: row.name,
                type: row.type,
                thumb: row.thumb,
                content: row.content,
                is_divide: row.is_divide,
                id: row.id,
                state: newState
            }).then(result => {
                if (result.code === 200) {
                    this.$message.success('状态更新成功');
                    this.fetchAdminList();
                } else {
                    this.$message.error(result.msg || '状态更新失败');
                }
            });
        },
        handleDelete(data) {
            this.$confirm('此操作将永久删除该文件, 是否继续?', '提示', {
                confirmButtonText: '确定',
                cancelButtonText: '取消',
                type: 'warning'
            }).then(() => {
                // 用户点击了确定按钮
                this.$http.post('/admin/single/del', {
                    id: data.id,
                    state: "-1"
                }).then(result => {
                    if (result.code === 200) {
                        this.$message.success(result.msg);
                        this.fetchAdminList();
                    } else {
                        this.$message.error(result.msg);
                    }
                });
            }).catch(() => {
                // 用户点击了取消按钮
                this.$message({
                    type: 'info',
                    message: '已取消删除'
                });
            });
        },
        submitForm() {
            if (!this.adminForm.thumb || !this.adminForm.thumb) {
                this.$message.error('请确保已上传封面图和详情图');
                return;
            }
            this.$refs.adminForm.validate(valid => {
                if (valid) {
                    // 假设后端接口需要 id 来确定要编辑的记录，这里将 adminForm 中的 id 一起传递
                    this.$http.post('/admin/single/edit', this.adminForm).then(result => {
                        if (result.code === 200) {
                            this.$message.success(result.msg);
                            this.addDialogVisible = false;
                            this.editDialogVisible = false;
                            this.fetchAdminList();
                        } else {
                            this.$message.error(result.msg);
                        }
                    });
                }
            });
        }
    }
};
</script>
<style lang="less" scoped>
.avatar-uploader .el-upload {
    border: 1px dashed #d9d9d9;
    border-radius: 6px;
    cursor: pointer;
    position: relative;
    overflow: hidden;
}

.avatar-uploader .el-upload:hover {
    border-color: #409EFF;
}

.avatar-uploader-icon {
    font-size: 28px;
    color: #8c939d;
    width: 178px;
    height: 178px;
    line-height: 178px;
    text-align: center;
}

.avatar {
    width: 178px;
    height: 178px;
    display: block;
}

/deep/ .el-dialog__header {
    padding: 10px !important;
    text-align: center;
}

.admin-page {
    padding: 24px;
    background: #fff;
    border-radius: 8px;
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.06);

    .page-header {
        margin-bottom: 24px;
        padding-bottom: 16px;
        border-bottom: 1px solid #f0f2f5;

        .header-title {
            font-size: 20px;
            font-weight: 600;
            color: #1f2937;
            line-height: 1.4;
        }
    }

    .table-header {
        margin-bottom: 24px;
        display: flex;
        justify-content: space-between;
        align-items: center;

        .table-title {
            font-size: 16px;
            font-weight: 500;
            color: #374151;
        }

        .table-actions {
            .el-button {
                margin-left: 12px;
                transition: all 0.3s;

                &:hover {
                    transform: translateY(-1px);
                }
            }
        }
    }

    .el-tabs {
        margin-top: 16px;

        :deep(.el-tabs__header) {
            margin-bottom: 28px;
            border-bottom: 2px solid #f0f2f5;
        }

        :deep(.el-tabs__item) {
            font-size: 15px;
            padding: 0 28px;
            height: 44px;
            line-height: 44px;
            transition: all 0.3s;

            &.is-active {
                color: #2563eb;
                font-weight: 500;
            }

            &:hover {
                color: #2563eb;
            }
        }

        :deep(.el-tabs__active-bar) {
            height: 2px;
            background-color: #2563eb;
            transition: all 0.3s cubic-bezier(0.645, 0.045, 0.355, 1);
        }
    }

    .el-table {
        margin-top: 12px;
        border-radius: 8px;
        overflow: hidden;

        :deep(th) {
            background-color: #f9fafb !important;
            font-weight: 500;
            color: #4b5563;
        }

        :deep(td) {
            padding: 12px 0;
        }

        .delete-btn {
            color: #dc2626;
            transition: all 0.3s;

            &:hover {
                color: #ef4444;
            }
        }
    }

    .el-pagination {
        margin-top: 24px;
        padding: 12px 0;
        text-align: right;

        :deep(.el-pagination__total) {
            margin-right: 12px;
        }

        :deep(.btn-prev),
        :deep(.btn-next) {
            border-radius: 4px;
            background-color: #fff;
        }

        :deep(.el-pager li) {
            border-radius: 4px;
            background-color: #fff;

            &.active {
                background-color: #2563eb;
            }
        }
    }

    .el-dialog {
        border-radius: 12px;
        overflow: hidden;
        max-height: 90vh;
        display: flex;
        flex-direction: column;

        :deep(.el-dialog__header) {
            padding: 20px 24px !important;
            border-bottom: 1px solid #f0f2f5;
            margin: 0;

            .el-dialog__title {
                font-size: 18px;
                font-weight: 600;
                color: #1f2937;
            }
        }

        :deep(.el-dialog__body) {
            padding: 32px 24px;
            flex: 1;
            overflow-y: auto;

            .el-form-item {
                .el-input,
                .el-select {
                    width: 320px;
                }
            }
        }

        :deep(.el-tree) {
            max-height: 300px;
            overflow-y: auto;
            border: 1px solid #DCDFE6;
            border-radius: 4px;
            padding: 10px;
        }

        :deep(.el-dialog__footer) {
            padding: 16px 24px;
            border-top: 1px solid #f0f2f5;
        }

        :deep(.el-form-item__label) {
            font-weight: 500;
            color: #374151;
        }

        :deep(.el-button) {
            padding: 8px 20px;
            transition: all 0.3s;

            &:hover {
                transform: translateY(-1px);
            }
        }
    }
}

.tip-text {
    font-size: 12px;
    color: #999;
    margin-top: 5px;
    display: block;
}

/deep/ .el-tab-pane {
    height: 650px;
    overflow-y: auto;
}

</style>


<el-dialog title="二维码" :visible.sync="qrCodeDialogVisible" width="300px" :close-on-click-modal="false">
<div style="text-align: center;">
    <qrcode-vue :value="currentQRCode" :size="200" level="H"/>
</div>
</el-dialog>
}
-->

